import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import com.sun.media.sound.RIFFInvalidDataException;

import javafx.scene.chart.PieChart.Data;

public class SyncLockThreadCommunication {
	static class DataWrap {
		int data;
		boolean flag;
		
		private final Lock lock = new ReentrantLock();
		private final Condition condition = lock.newCondition();
		
		public void addThreadA() {
			lock.lock();
			try {
				if (flag) {
					try {
						condition.await();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
				data++;
				System.out.println(Thread.currentThread().getName() + " " + data);
				flag = true;
				condition.signal();
			} finally {
				lock.unlock();
			}
		}
		
		public void addThreadB() {
			lock.lock();
			try {
				if (!flag) {
					try {
						condition.await();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
				data++;
				System.out.println(Thread.currentThread().getName() + " " + data);
				flag = false;
				condition.signal();
			} finally {
				lock.unlock();
			}
		}
	}
	
	static class ThreadA extends Thread{
		DataWrap dataWrap;
		
		public ThreadA(DataWrap dataWrap) {
			this.dataWrap = dataWrap;
		}
		
		@Override
		public void run() {
			for (int i = 0; i < 10; i++) {
				dataWrap.addThreadA();
			}
		}
	}
	
	static class ThreadB extends Thread{
		DataWrap dataWrap;
		
		public ThreadB(DataWrap dataWrap) {
			this.dataWrap = dataWrap;
		}
		
		@Override
		public void run() {
			for (int i = 0; i < 10; i++) {
				dataWrap.addThreadB();
			}
		}
	}
	
	public static void main(String[] args) {
		//实现两个线程轮流对数据进行加一操作
		
		DataWrap dataWrap = new DataWrap();
		new ThreadA(dataWrap).start();
		new ThreadB(dataWrap).start();
	}

}
